package com.alex.tkmybatis.common.support;

import org.apache.ibatis.reflection.property.PropertyNamer;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import java.util.Map;

/**
 * @author alexchan
 * @param <T>
 */
public abstract class AbstractExampleWrapper<T> extends Example {

    protected Criteria criteria;

    private Map<String, String> columnMap = null;

    private boolean initColumnMap = false;

    /**
     * 默认exists为true
     *
     * @param entityClass
     */
    public AbstractExampleWrapper(Class<?> entityClass) {
        super(entityClass);
    }

    protected String columnToString(SFunction<T, ?> column) {
        return getColumn(LambdaUtils.resolve(column));
    }

    /**
     * 获取 SerializedLambda 对应的列信息，从 lambda 表达式中推测实体类
     * <p>
     * 如果获取不到列信息，那么本次条件组装将会失败
     *
     * @param lambda lambda 表达式
     * @return 列
     * @throws
     * @see SerializedLambda#getImplClass()
     * @see SerializedLambda#getImplMethodName()
     */
    private String getColumn(SerializedLambda lambda) {
        String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
        Class<?> aClass = lambda.getInstantiatedMethodType();
        if (!initColumnMap) {
            columnMap = LambdaUtils.getColumnMap(aClass);
        }
        Assert.notNull(columnMap, LambdaUtils.format("can not find lambda cache for this entity [%s]", aClass.getName()));
        String column = columnMap.get(LambdaUtils.formatKey(fieldName));
        Assert.notNull(column, LambdaUtils.format("can not find lambda cache for this property [%s] of entity [%s]",
                fieldName, aClass.getName()));
        return column;
    }
}